package com.czy.moudle.pdm.service.impl;

import com.czy.moudle.pdm.service.PDMParseService;
import com.czy.moudle.pdm.util.DocUtils;
import com.czy.moudle.pdm.vo.Entity;
import com.czy.moudle.pdm.vo.Field;
import com.czy.util.StringUtils;
import org.apache.commons.collections.CollectionUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

/**
 * pdm解析实现类
 *
 * @author 陈致远
 */
public class PDMParseServiceImpl implements PDMParseService {
    @Override
    public Document getDocumentByPath(String pdmPath) {
        assert StringUtils.isNotEmpty(pdmPath);

        pdmPath = Class.class.getClass().getResource("/").getPath() + pdmPath;
        SAXReader reader = new SAXReader();
        Document document = null;

        File file = new File(pdmPath);
        if(null == file) throw new RuntimeException("找不到pdm文件" + pdmPath);

        try {
            document = reader.read(file);
        } catch (DocumentException e) {
            throw new RuntimeException("pdm转换失败：" + pdmPath, e);
        }
        return document;
    }

    @Override
    public List<Entity> parseDoc(Document document) {
        List<Entity> result = new ArrayList<>();

        Element root = document.getRootElement();

        //pdm中所有表配置信息，封装DBTable
        List<Element> tables = root.selectNodes(TABLE_SPAN_PATH);

        //遍历表配置信息，
        if (CollectionUtils.isNotEmpty(tables)) {
            for (Element table : tables) {
                //名称节点：字段注释
                Node nameElement = table.selectSingleNode(NAME_PATH);
                //编码节点：表名称
                Node codeElement = table.selectSingleNode(CODE_PATH);

                Entity entity = new Entity();
                entity.setTableName(codeElement.getText());
                entity.setComment(nameElement.getText());

                //获取表配置下的所有字段配置信息
                List<Element> columns = table.selectNodes(COLUMN_SPAN_PATH);
                List<Field> fields = getDbColumns(columns);
                entity.setColumnList(fields);

                result.add(entity);
            }
        }
        return result;
    }

    /**
     * 通过PDM字段配置，封装DBColumn
     *
     * @param columns
     * @return
     */
    private List<Field> getDbColumns(List<Element> columns) {
        List<Field> fields = null;

        if(CollectionUtils.isNotEmpty(columns)){
            fields = new ArrayList<>();

            for (Element column : columns) {
                Field field = new Field();
                field.setColumnName(column.selectSingleNode(CODE_PATH).getText());
                Node commonNode = column.selectSingleNode(COMMON_PATH);
                field.setComment(DocUtils.getNodeText(commonNode));

                Node typeNode = column.selectSingleNode(TYPE_PATH);
                field.setColumnType(DocUtils.getNodeText(typeNode));

                Node lengthNode = column.selectSingleNode(LENGTH_PATH);
                field.setLength(null == lengthNode ? 0 : Long.valueOf(lengthNode.getText()));
                fields.add(field);
            }
        }
        return fields;
    }
}
